﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace MX.Core.Http.WebAction
{
    /// <summary>
    /// HTML页面操作基类，主要提供页面获取常用的函数和验证码操作
    /// </summary>
    abstract public class WebPageAction : WebAction
    {
       
        static Dictionary<string, string> _cacheHtml = new Dictionary<string, string>();
        protected readonly static Regex regNum = new Regex(@"[\d]+");
        protected readonly static Regex regScript = new Regex("<script[^>]*>[\\s\\S]+?</script>", RegexOptions.IgnoreCase);
        protected readonly static Regex regSecondJson = new Regex("[\\'\\\"]*?[\\w]+[-]*?[\\'\\\"]*?[\\s]*?:[\\s]*?{[\\s\\S]+?}");
        protected readonly static Regex regCookie = new Regex(@"(?<=domain\=[^\=]+),", RegexOptions.IgnoreCase);
        protected readonly static Regex regInput = new Regex(@"\<input[^\<]+\>", RegexOptions.IgnoreCase);
        readonly protected static Regex regName = new Regex("(name\\=\\'[^\\=]+\\'|name\\=\\\"[^\\=]+\\\"|name\\=[^\\\"]+([\\s]+|(?=\\>)))", RegexOptions.IgnoreCase);
        readonly protected static Regex regValue = new Regex("(value\\=\\'[^\\=]+\\'|value\\=\\\"[^\\\"]+\\\"|value\\=[^\\\"]+([\\s]+|(?=\\>)))", RegexOptions.IgnoreCase);
        readonly protected static Regex regForm = new Regex(@"<form.+>[\s\S]*?<\/form>", RegexOptions.IgnoreCase);
        readonly protected static Regex regUnicode = new Regex(@"(\\u[a-z0-9]{4})+", RegexOptions.IgnoreCase);

        protected readonly static Regex regEmail = new Regex(@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*");
 

        public WebPageAction()
        { }
      

      


        protected NameValueCollection CombineForm(NameValueCollection post, NameValueCollection custom)
        {
            if (custom != null)
                foreach (var key in custom.AllKeys)
                {
                    if (post.AllKeys.Contains(key))
                    {
                        post[key] = custom[key];
                    }
                    else
                    {
                        post.Add(key, custom[key]);
                    }
                }
            return post;
        }
        /// <summary>
        /// 得到某一个域名下的cookie文本
        /// </summary>
        /// <param name="domain"></param>
        /// <param name="mainKey"></param>
        /// <param name="childKey"></param>
        /// <returns></returns>

        protected string GetCookie(string domain, string mainKey, string childKey = "")
        {
            var cks = _cookieManager.GetCookies(new Uri(domain).Host);
            if (cks[mainKey] != null)
            {
                string child = cks[mainKey].Value;
                if (childKey == "")
                {
                    return child;
                }
                var cls = child.Split('&');
                for (int i = 0; i < cls.Length; i++)
                {
                    var nv = cls[i].Split('=');
                    if (nv[0] == childKey)
                    {
                        return nv[1];
                    }
                }
            }
            return null;
        }

       
        /// <summary>
        /// 将表单html文本转换为NameValueCollection对象
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        public NameValueCollection GetFormDataByFormHtml(string form)
        {
            NameValueCollection post = new NameValueCollection();
            string strHtml = form;
            var masInput = regInput.Matches(strHtml);
            foreach (Match maInput in masInput)
            {
                string name = regName.Match(maInput.Value).Value;
                if (String.IsNullOrEmpty(name))
                    continue;
                int start = 0;
                int length = 0;
                if (name.Contains("=\""))
                {
                    start = name.IndexOf("=\"") + 2;
                    length = name.Length - start - 1;
                }
                else if (name.Contains("='"))
                {
                    start = name.IndexOf("='") + 2;
                    length = name.Length - start - 1;
                }
                else
                {
                    start = name.IndexOf("=") + 1;
                    length = name.Length - start;
                }
                name = name.Substring(start, length);
                string value = regValue.Match(maInput.Value).Value;
                if (value.Contains("=\""))
                {
                    start = value.IndexOf("=\"") + 2;
                    length = value.Length - start - 1;
                }
                else if (value.Contains("='"))
                {
                    start = value.IndexOf("='") + 2;
                    length = value.Length - start - 1;
                }
                else
                {
                    start = value.IndexOf("=") + 1;
                    length = value.Length - start;
                }
                if (value.Length > length)
                    value = value.Substring(start, length);
                if (post.AllKeys.Contains(name))
                {
                    continue;
                }
                post.Add(name, value);
            }
            return post;
        }

         
        /// <summary>
        /// 解析javascript中json字符串内容
        /// </summary>
        /// <param name="html">包含javascript html文本</param>
        /// <param name="prefix">参数前缀</param>
        /// <param name="isChild">是否检查子项</param>
        /// <returns></returns>
        protected Dictionary<string, string> GetScriptParameters(string html, string prefix, bool isChild = false)
        {
            var masScript = regScript.Matches(html);
            Regex regParam = new Regex("(?<=" + prefix + @"[\s]*?\=[\s]*?{)[\s\S]+?(?=};)", RegexOptions.IgnoreCase);
            Regex regParam2 = new Regex("(?<=" + prefix + "\\\"[\\s]*?:[\\s]*?{)[\\s\\S]+?(?=}.)", RegexOptions.IgnoreCase);
            Dictionary<string, string> pars = new Dictionary<string, string>();
            foreach (Match maScr in masScript)
            {
                MatchCollection masParam = null;
                if (!isChild)
                {
                    masParam = regParam.Matches(maScr.Value);
                }
                else
                {
                    masParam = regParam2.Matches(maScr.Value);
                }
                foreach (Match maParam in masParam)
                {
                    if (!maParam.Success) continue;
                    Dictionary<string, string> nvs = ParseJson(maParam.Value);
                    foreach (var nv in nvs)
                    {
                        if (pars.ContainsKey(nv.Key))
                            pars[nv.Key] = nv.Value;
                        else
                            pars.Add(nv.Key, nv.Value);
                    }
                }
            }
            return pars;
        }

        /// <summary>
        /// 解析json字符串
        /// </summary>
        /// <param name="json"></param>
        /// <returns></returns>
        protected Dictionary<string, string> ParseJson(string json)
        {
            Dictionary<string, string> pars = new Dictionary<string, string>();
            string firstJson = regSecondJson.Replace(json, "");
            var items = firstJson.Split(',');
            foreach (var item in items)
            {
                if (item.Contains(":"))
                {
                    var kv = item.Split(':');
                    if (kv.Length > 1)
                    {
                        string key = kv[0].Trim().Replace("\r", "").Replace("\n", "");
                        if (key.IndexOf("'") == 0 || key.IndexOf("\"") == 0)
                        {
                            key = key.Substring(1, key.Length - 2);
                        }
                        string value = kv[1].Trim().Replace("\r", "").Replace("\n", "");
                        if (value.IndexOf("'") == 0 || value.IndexOf("\"") == 0)
                        {
                            value = value.Substring(1, value.Length - 2);
                        }
                        if (pars.ContainsKey(key))
                            pars[key] = value;
                        else
                            pars.Add(key, value);
                    }
                }
            }
            return pars;
        }
        /// <summary>
        /// 按照约束获取html内的表单数据
        /// </summary>
        /// <param name="html">html文本</param>
        /// <param name="constraint">一般为表单的条件</param>
        /// <returns></returns>
        protected NameValueCollection GetFormDataByConstraint(string html, string constraint = null)
        {
            Regex regConstraintForm = null;
            if (constraint == null)
                regConstraintForm = regForm;
            else
                regConstraintForm = new Regex("<form.*?" + constraint + ".*?>[\\s\\S]*?<\\/form>", RegexOptions.IgnoreCase);
            return GetFormDataByFormHtml(regConstraintForm.Match(html).Value);
        }
    }
}
